package PrjUtils

import (
	"dgo/goutils/utils"
	"fmt"
	"os"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

type CanWriteMonitor struct {
	writeflag int32
	path      string
	testFile  string
}

func NewCanWriteMonitor(path string) *CanWriteMonitor {
	rval := &CanWriteMonitor{path: path}
	if strings.HasSuffix(path, utils.PathSeparator) {
		rval.testFile = fmt.Sprintf("%s%d-test.log", path, os.Getpid())
	} else {
		rval.testFile = fmt.Sprintf("%s%s%d-test.log", path, utils.PathSeparator, os.Getpid())
	}

	return rval
}

func (this *CanWriteMonitor) startTestWrite() error {
	return utils.RewriteFile(this.testFile, []byte(utils.NowString()))
}

func (this *CanWriteMonitor) TestWrite() error {
	if this.writeflag == 1 {
		return fmt.Errorf("上次写入还未结束, 写入冲突!!!")
	}

	if atomic.CompareAndSwapInt32(&this.writeflag, 0, 1) {
		var writeErr error = nil
		var wait sync.WaitGroup
		wait.Add(1)
		go func() {
			t1 := time.Now()
			writeErr = this.startTestWrite()
			t2 := time.Now().Sub(t1)
			this.writeflag = 0
			wait.Done()
			if t2.Seconds() > 5 {
				if writeErr != nil {
					fmt.Fprintf(os.Stderr, "[%s]TestWrite写入超时[%.2f]s, 异常:%s\r\n", utils.NowString(), t2.Seconds(), writeErr.Error())
				} else {
					fmt.Fprintf(os.Stderr, "[%s]TestWrite写入超时[%.2f]s, 无异常\r\n", utils.NowString(), t2.Seconds())
				}
			}
		}()

		if utils.WaitFor(&wait, time.Second*5) { // 写入线程执行完成
			return writeErr
		} else { // 写入超时
			return fmt.Errorf("写入超时")
		}
	}

	return fmt.Errorf("写入被抢占, 写入冲突!!!")
}
